import { defineStore } from 'pinia'

/**
 * 主题类型
 * @description 定义应用的主题类型
 */
type Theme = 'light' | 'dark' | 'auto'

/**
 * 布局类型
 * @description 定义应用的布局类型
 */
type Layout = 'default' | 'compact' | 'wide'

/**
 * 通知类型
 * @description 定义通知的类型
 */
type NotificationType = 'success' | 'warning' | 'error' | 'info'

/**
 * 通知接口
 * @description 定义通知的基本结构
 */
export interface Notification {
    id: string
    type: NotificationType
    title: string
    message: string
    duration?: number
    showClose?: boolean
    timestamp: number
}

/**
 * 模态框接口
 * @description 定义模态框的基本结构
 */
export interface Modal {
    id: string
    title: string
    content: string
    type: 'confirm' | 'alert' | 'custom'
    showClose?: boolean
    showCancel?: boolean
    confirmText?: string
    cancelText?: string
    onConfirm?: () => void
    onCancel?: () => void
}

/**
 * 导航状态接口
 * @description 定义导航相关的状态信息
 */
export interface NavigationState {
    isMobileMenuOpen: boolean
    isSearchOpen: boolean
    isCategoryDropdownOpen: boolean
    activeRoute: string
    breadcrumbs: Array<{
        name: string
        path: string
    }>
}

/**
 * 页面状态接口
 * @description 定义页面相关的状态信息
 */
export interface PageState {
    isLoading: boolean
    isScrolled: boolean
    scrollTop: number
    windowWidth: number
    windowHeight: number
}

/**
 * UI状态管理Store
 * @description 管理用户界面相关的所有状态，包括主题、布局、导航、通知等
 */
export const useUIStore = defineStore('ui', {
    state: () => ({
        // 主题设置
        theme: 'auto' as Theme,

        // 布局设置
        layout: 'default' as Layout,

        // 导航状态
        navigation: {
            isMobileMenuOpen: false,
            isSearchOpen: false,
            isCategoryDropdownOpen: false,
            activeRoute: '/',
            breadcrumbs: []
        } as NavigationState,

        // 页面状态
        page: {
            isLoading: false,
            isScrolled: false,
            scrollTop: 0,
            windowWidth: window.innerWidth,
            windowHeight: window.innerHeight
        } as PageState,

        // 通知列表
        notifications: [] as Notification[],

        // 模态框列表
        modals: [] as Modal[],

        // 侧边栏状态
        sidebar: {
            isOpen: false,
            width: 280
        },

        // 加载状态
        loading: {
            global: false,
            page: false,
            component: false
        },

        // 错误状态
        error: null as string | null
    }),

    getters: {
        /**
         * 获取当前主题
         * @description 返回当前设置的主题
         * @returns {Theme} 主题类型
         */
        getCurrentTheme: (state) => state.theme,

        /**
         * 获取当前布局
         * @description 返回当前设置的布局
         * @returns {Layout} 布局类型
         */
        getCurrentLayout: (state) => state.layout,

        /**
         * 获取导航状态
         * @description 返回当前的导航状态
         * @returns {NavigationState} 导航状态对象
         */
        getNavigationState: (state) => state.navigation,

        /**
         * 获取页面状态
         * @description 返回当前的页面状态
         * @returns {PageState} 页面状态对象
         */
        getPageState: (state) => state.page,

        /**
         * 获取通知列表
         * @description 返回当前的通知列表
         * @returns {Notification[]} 通知数组
         */
        getNotifications: (state) => state.notifications,

        /**
         * 获取模态框列表
         * @description 返回当前的模态框列表
         * @returns {Modal[]} 模态框数组
         */
        getModals: (state) => state.modals,

        /**
         * 获取侧边栏状态
         * @description 返回当前的侧边栏状态
         * @returns {Object} 侧边栏状态对象
         */
        getSidebarState: (state) => state.sidebar,

        /**
         * 获取加载状态
         * @description 返回当前的加载状态
         * @returns {Object} 加载状态对象
         */
        getLoadingState: (state) => state.loading,

        /**
         * 检查是否为移动端
         * @description 根据窗口宽度判断是否为移动设备
         * @returns {boolean} 是否为移动端
         */
        isMobile: (state) => state.page.windowWidth < 768,

        /**
         * 检查是否为平板端
         * @description 根据窗口宽度判断是否为平板设备
         * @returns {boolean} 是否为平板端
         */
        isTablet: (state) => state.page.windowWidth >= 768 && state.page.windowWidth < 1024,

        /**
         * 检查是否为桌面端
         * @description 根据窗口宽度判断是否为桌面设备
         * @returns {boolean} 是否为桌面端
         */
        isDesktop: (state) => state.page.windowWidth >= 1024,

        /**
         * 获取当前通知数量
         * @description 返回当前通知的数量
         * @returns {number} 通知数量
         */
        getNotificationCount: (state) => state.notifications.length,

        /**
         * 获取当前模态框数量
         * @description 返回当前模态框的数量
         * @returns {number} 模态框数量
         */
        getModalCount: (state) => state.modals.length
    },

    actions: {
        /**
         * 切换主题
         * @description 在浅色、深色、自动主题之间循环切换
         */
        toggleTheme() {
            const themes: Theme[] = ['light', 'dark', 'auto']
            const currentIndex = themes.indexOf(this.theme)
            const nextIndex = (currentIndex + 1) % themes.length
            this.theme = themes[nextIndex]

            // 应用主题
            this.applyTheme()

            // 保存到本地存储
            localStorage.setItem('theme', this.theme)
        },

        /**
         * 设置主题
         * @description 直接设置指定的主题
         * @param {Theme} theme 要设置的主题
         */
        setTheme(theme: Theme) {
            this.theme = theme
            this.applyTheme()
            localStorage.setItem('theme', theme)
        },

        /**
         * 应用主题
         * @description 将当前主题应用到DOM元素
         */
        applyTheme() {
            const root = document.documentElement

            if (this.theme === 'auto') {
                // 根据系统偏好设置主题
                const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
                root.setAttribute('data-theme', prefersDark ? 'dark' : 'light')
            } else {
                root.setAttribute('data-theme', this.theme)
            }
        },

        /**
         * 设置布局
         * @description 设置应用的布局类型
         * @param {Layout} layout 布局类型
         */
        setLayout(layout: Layout) {
            this.layout = layout
            localStorage.setItem('layout', layout)
        },

        /**
         * 切换移动端菜单
         * @description 切换移动端菜单的显示状态
         */
        toggleMobileMenu() {
            this.navigation.isMobileMenuOpen = !this.navigation.isMobileMenuOpen

            // 控制body滚动
            if (this.navigation.isMobileMenuOpen) {
                document.body.style.overflow = 'hidden'
            } else {
                document.body.style.overflow = ''
            }
        },

        /**
         * 关闭移动端菜单
         * @description 关闭移动端菜单并恢复页面滚动
         */
        closeMobileMenu() {
            this.navigation.isMobileMenuOpen = false
            document.body.style.overflow = ''
        },

        /**
         * 切换搜索框
         * @description 切换搜索框的显示状态
         */
        toggleSearch() {
            this.navigation.isSearchOpen = !this.navigation.isSearchOpen
        },

        /**
         * 关闭搜索框
         * @description 关闭搜索框
         */
        closeSearch() {
            this.navigation.isSearchOpen = false
        },

        /**
         * 切换分类下拉菜单
         * @description 切换分类下拉菜单的显示状态
         */
        toggleCategoryDropdown() {
            this.navigation.isCategoryDropdownOpen = !this.navigation.isCategoryDropdownOpen
        },

        /**
         * 关闭分类下拉菜单
         * @description 关闭分类下拉菜单
         */
        closeCategoryDropdown() {
            this.navigation.isCategoryDropdownOpen = false
        },

        /**
         * 设置活动路由
         * @description 设置当前活动的路由路径
         * @param {string} route 路由路径
         */
        setActiveRoute(route: string) {
            this.navigation.activeRoute = route
        },

        /**
         * 设置面包屑
         * @description 设置页面的面包屑导航
         * @param {Array<{name: string, path: string}>} breadcrumbs 面包屑数组
         */
        setBreadcrumbs(breadcrumbs: Array<{ name: string; path: string }>) {
            this.navigation.breadcrumbs = breadcrumbs
        },

        /**
         * 添加通知
         * @description 添加一个新的通知到通知列表
         * @param {Omit<Notification, 'id' | 'timestamp'>} notification 通知信息
         * @returns {string} 通知ID
         */
        addNotification(notification: Omit<Notification, 'id' | 'timestamp'>) {
            const id = Date.now().toString()
            const newNotification: Notification = {
                ...notification,
                id,
                timestamp: Date.now()
            }

            this.notifications.push(newNotification)

            // 自动移除通知
            if (notification.duration !== 0) {
                setTimeout(() => {
                    this.removeNotification(id)
                }, notification.duration || 3000)
            }

            return id
        },

        /**
         * 移除通知
         * @description 根据ID移除指定的通知
         * @param {string} id 通知ID
         */
        removeNotification(id: string) {
            const index = this.notifications.findIndex(n => n.id === id)
            if (index > -1) {
                this.notifications.splice(index, 1)
            }
        },

        /**
         * 清除所有通知
         * @description 清除所有通知
         */
        clearNotifications() {
            this.notifications = []
        },

        /**
         * 显示成功通知
         * @description 显示一个成功类型的通知
         * @param {string} message 通知消息
         * @param {string} title 通知标题，默认为'成功'
         * @returns {string} 通知ID
         */
        showSuccess(message: string, title: string = '成功') {
            return this.addNotification({
                type: 'success',
                title,
                message
            })
        },

        /**
         * 显示警告通知
         * @description 显示一个警告类型的通知
         * @param {string} message 通知消息
         * @param {string} title 通知标题，默认为'警告'
         * @returns {string} 通知ID
         */
        showWarning(message: string, title: string = '警告') {
            return this.addNotification({
                type: 'warning',
                title,
                message
            })
        },

        /**
         * 显示错误通知
         * @description 显示一个错误类型的通知
         * @param {string} message 通知消息
         * @param {string} title 通知标题，默认为'错误'
         * @returns {string} 通知ID
         */
        showError(message: string, title: string = '错误') {
            return this.addNotification({
                type: 'error',
                title,
                message
            })
        },

        /**
         * 显示信息通知
         * @description 显示一个信息类型的通知
         * @param {string} message 通知消息
         * @param {string} title 通知标题，默认为'信息'
         * @returns {string} 通知ID
         */
        showInfo(message: string, title: string = '信息') {
            return this.addNotification({
                type: 'info',
                title,
                message
            })
        },

        /**
         * 显示确认对话框
         * @description 显示一个确认对话框
         * @param {Object} options 对话框选项
         * @param {string} options.title 对话框标题
         * @param {string} options.content 对话框内容
         * @param {string} options.confirmText 确认按钮文本
         * @param {string} options.cancelText 取消按钮文本
         * @param {Function} options.onConfirm 确认回调
         * @param {Function} options.onCancel 取消回调
         * @returns {string} 模态框ID
         */
        showConfirm(options: {
            title: string
            content: string
            confirmText?: string
            cancelText?: string
            onConfirm?: () => void
            onCancel?: () => void
        }) {
            const id = Date.now().toString()
            const modal: Modal = {
                id,
                title: options.title,
                content: options.content,
                type: 'confirm',
                showClose: true,
                showCancel: true,
                confirmText: options.confirmText || '确认',
                cancelText: options.cancelText || '取消',
                onConfirm: options.onConfirm,
                onCancel: options.onCancel
            }

            this.modals.push(modal)
            return id
        },

        /**
         * 显示警告对话框
         * @description 显示一个警告对话框
         * @param {Object} options 对话框选项
         * @param {string} options.title 对话框标题
         * @param {string} options.content 对话框内容
         * @param {string} options.confirmText 确认按钮文本
         * @param {Function} options.onConfirm 确认回调
         * @returns {string} 模态框ID
         */
        showAlert(options: {
            title: string
            content: string
            confirmText?: string
            onConfirm?: () => void
        }) {
            const id = Date.now().toString()
            const modal: Modal = {
                id,
                title: options.title,
                content: options.content,
                type: 'alert',
                showClose: true,
                showCancel: false,
                confirmText: options.confirmText || '确定',
                onConfirm: options.onConfirm
            }

            this.modals.push(modal)
            return id
        },

        /**
         * 移除模态框
         * @description 根据ID移除指定的模态框
         * @param {string} id 模态框ID
         */
        removeModal(id: string) {
            const index = this.modals.findIndex(m => m.id === id)
            if (index > -1) {
                this.modals.splice(index, 1)
            }
        },

        /**
         * 清除所有模态框
         * @description 清除所有模态框
         */
        clearModals() {
            this.modals = []
        },

        /**
         * 切换侧边栏
         * @description 切换侧边栏的显示状态
         */
        toggleSidebar() {
            this.sidebar.isOpen = !this.sidebar.isOpen
        },

        /**
         * 打开侧边栏
         * @description 打开侧边栏
         */
        openSidebar() {
            this.sidebar.isOpen = true
        },

        /**
         * 关闭侧边栏
         * @description 关闭侧边栏
         */
        closeSidebar() {
            this.sidebar.isOpen = false
        },

        /**
         * 设置侧边栏宽度
         * @description 设置侧边栏的宽度
         * @param {number} width 宽度值
         */
        setSidebarWidth(width: number) {
            this.sidebar.width = width
        },

        /**
         * 设置全局加载状态
         * @description 设置全局加载状态
         * @param {boolean} loading 是否加载中
         */
        setGlobalLoading(loading: boolean) {
            this.loading.global = loading
        },

        /**
         * 设置页面加载状态
         * @description 设置页面加载状态
         * @param {boolean} loading 是否加载中
         */
        setPageLoading(loading: boolean) {
            this.loading.page = loading
        },

        /**
         * 设置组件加载状态
         * @description 设置组件加载状态
         * @param {boolean} loading 是否加载中
         */
        setComponentLoading(loading: boolean) {
            this.loading.component = loading
        },

        /**
         * 更新页面滚动状态
         * @description 更新页面的滚动状态
         * @param {number} scrollTop 滚动距离
         */
        updateScrollState(scrollTop: number) {
            this.page.scrollTop = scrollTop
            this.page.isScrolled = scrollTop > 0
        },

        /**
         * 更新窗口尺寸
         * @description 更新窗口的宽度和高度
         */
        updateWindowSize() {
            this.page.windowWidth = window.innerWidth
            this.page.windowHeight = window.innerHeight
        },

        /**
         * 设置错误信息
         * @description 设置错误信息
         * @param {string | null} error 错误信息
         */
        setError(error: string | null) {
            this.error = error
        },

        /**
         * 清除错误信息
         * @description 清除错误信息
         */
        clearError() {
            this.error = null
        },

        /**
         * 初始化UI状态
         * @description 初始化UI状态，包括主题、布局、事件监听等
         */
        initializeUI() {
            // 从本地存储恢复主题
            const savedTheme = localStorage.getItem('theme') as Theme
            if (savedTheme) {
                this.theme = savedTheme
            }

            // 从本地存储恢复布局
            const savedLayout = localStorage.getItem('layout') as Layout
            if (savedLayout) {
                this.layout = savedLayout
            }

            // 应用主题
            this.applyTheme()

            // 监听窗口尺寸变化
            window.addEventListener('resize', () => {
                this.updateWindowSize()
            })

            // 监听滚动事件
            window.addEventListener('scroll', () => {
                this.updateScrollState(window.scrollY)
            })

            // 监听系统主题变化
            window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
                if (this.theme === 'auto') {
                    this.applyTheme()
                }
            })
        }
    }
})
